package com.example.processor

import com.google.devtools.ksp.processing.*
import com.google.devtools.ksp.symbol.KSAnnotated
import com.google.devtools.ksp.symbol.KSClassDeclaration

@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.SOURCE)
annotation class AutoGenerateCRUD(
    val basePath: String,
)

private class AnnotationCrudProcessor(
    private val codeGenerator: CodeGenerator,
    private val logger: KSPLogger,
) : SymbolProcessor {

    override fun process(resolver: Resolver): List<KSAnnotated> {
        val symbols = resolver.getSymbolsWithAnnotation(AutoGenerateCRUD::class.qualifiedName!!)
            .filterIsInstance<KSClassDeclaration>()

        symbols.forEach { classDecl ->
            val annotation = classDecl.annotations
                .first { it.shortName.getShortName() == "AutoGenerateCRUD" }

            val basePath = annotation.arguments
                .first { it.name?.asString() == "basePath" }
                .value as String

            generateCrudMethods(classDecl, basePath)
        }

        return emptyList()
    }

    private fun generateCrudMethods(classDecl: KSClassDeclaration, basePath: String) {
        val packageName = classDecl.containingFile?.packageName?.asString() ?: ""
        val className = "${classDecl.simpleName.asString()}Generated"

        val file = codeGenerator.createNewFile(
            dependencies = Dependencies(false, classDecl.containingFile!!),
            packageName = packageName,
            fileName = className
        )
        file.write(
            """
            package $packageName
            
            import org.springframework.web.bind.annotation.*
            import org.springframework.http.ResponseEntity
            
            @RestController
            @RequestMapping("$basePath")
            class $className {
                
                @GetMapping
                fun getAll(): ResponseEntity<List<Any>> {
                    return ResponseEntity.ok(emptyList())
                }
                
                @GetMapping("/{id}")
                fun getById(@PathVariable id: Long): ResponseEntity<Any> {
                    return ResponseEntity.ok().build()
                }
                
                @PostMapping
                fun create(@RequestBody entity: Any): ResponseEntity<Any> {
                    return ResponseEntity.ok(entity)
                }
                
                @PutMapping("/{id}")
                fun update(@PathVariable id: Long, @RequestBody entity: Any): ResponseEntity<Any> {
                    return ResponseEntity.ok(entity)
                }
                
                @DeleteMapping("/{id}")
                fun delete(@PathVariable id: Long): ResponseEntity<Void> {
                    return ResponseEntity.noContent().build()
                }
            }
        """.trimIndent().toByteArray()
        )

        file.close()
    }
}

class User

class AnnotationCrudProcessorProvider : SymbolProcessorProvider {
    override fun create(environment: SymbolProcessorEnvironment): SymbolProcessor {
        return AnnotationCrudProcessor(
            codeGenerator = environment.codeGenerator,
            logger = environment.logger
        )
    }
}